package cn.zhfeat.hatch.web.utils.merchant;

import cn.zhfeat.utils.StringUtils;
import cn.zhfeat.utils.redis.RedisStringUtil;
import com.google.common.collect.Lists;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.security.MessageDigest;
import java.util.*;
import java.util.Map.Entry;


public class TokenUtil {

	private static String preAuthKey = RedisConfig.REDIS_KEY+":PREAUTH";//预授权码在redis中的KEY
	private static JsonParser parser =new JsonParser();
	private static TokenUtil intance = null;
	
	private TokenUtil(){
		initData();
	}

	public static TokenUtil getInstance(){
		if(intance == null){
			synchronized (TokenUtil.class) {
				if(intance == null){
					intance = new TokenUtil();
				}
			}
		}
		return intance;
	}
	
	private void initData() {
	}
		
	public String create_nonce_str() {
		String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String res = "";
		for (int i = 0; i < 16; i++) {
			Random rd = new Random();
			res += chars.charAt(rd.nextInt(chars.length() - 1));
		}
		return res;
	}
	
	public String getPreAuthCode() {
		return RedisStringUtil.getValue(preAuthKey);
	}
	
	public static void main(String[] args) {
		try {
			Properties P = ConfigUtil.getInstance().getProperties();
			String appid = P.getProperty("APPID");
			String component_access_token = "7_mV00w4xDXsiiGcTGOZfwPOtfwIv1KiTyuTlgmsO1gUBznFUhPbu7QqjXHzpinhQXTQQrcYGpuHeVTwRHJIGau2vOrwwN0QT9-jX2uDhDl07_gAUzHpEea26dHOGd0DuDOzQzyE9M_2dxB3U5MYMjAEAEQE";
			String OPEN_REFRESH_TOKEN = P.getProperty("OPEN_REFRESH_TOKEN")+"?component_access_token="+component_access_token;
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("component_appid", appid);
			params.put("authorizer_appid", "wx9219837a962c46bf");
			params.put("authorizer_refresh_token", "refreshtoken@@@zDivky5XrdMEbUyq2n--RhE-niiNg8uHi7tjiJQF4eE");
			String result = HttpUtil.jsonPost(OPEN_REFRESH_TOKEN, params);
			System.out.println("refreshAuthorizerToken result:"+result);
			JsonObject jsonObject = parser.parse(result).getAsJsonObject();
			System.out.println("refreshAuthorizerToken:::"+jsonObject);
			String authorizer_access_token = jsonObject.get("authorizer_access_token").getAsString();
			String authorizer_refresh_token = jsonObject.get("authorizer_refresh_token").getAsString();
			System.out.println("old:7_tUhL6BU0NWbsxLsieqdzsja28paetePzounY4_E-wETjbZ2ZKjA1TcBQ1UJklFdCh5e2QcQ_WFK8nj_JlHM2Ul6yNNGSWVHydNCOPf8543qIO8jeDxFNwjEX5wlnIUqsRr7OcE_y9zTo2dYFHQTfAIDYHK");
			System.out.println("new:"+authorizer_access_token);
			System.out.println("old:"+"refreshtoken@@@zDivky5XrdMEbUyq2n--RhE-niiNg8uHi7tjiJQF4eE");
			System.out.println("new:"+authorizer_refresh_token);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public String getComponentAccessToken(String verifyTicket) {
		try {
			Properties P = ConfigUtil.getInstance().getProperties();
			String appid = P.getProperty("APPID");
			String appsecret = P.getProperty("APPSECRET");
			String OPEN_COMPONENT_ACCESS_TOKEN = P.getProperty("OPEN_COMPONENT_ACCESS_TOKEN");
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("component_appid", appid);
			params.put("component_appsecret", appsecret);
			params.put("component_verify_ticket", verifyTicket);
			String result = HttpUtil.jsonPost(OPEN_COMPONENT_ACCESS_TOKEN, params);
			JsonObject jsonObject = parser.parse(result).getAsJsonObject();
//			System.out.println("jsonObject:::"+jsonObject.toString());
			String component_access_token = jsonObject.get("component_access_token").getAsString();
			return component_access_token;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public void refreshPreAuthCode(String component_access_token) {
		try {
			Properties P = ConfigUtil.getInstance().getProperties();
			String appid = P.getProperty("APPID");
			String OPEN_COMPONENT_ACCESS_TOKEN = P.getProperty("OPEN_PRE_AUTH_CODE")+"?component_access_token="+component_access_token;
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("component_appid", appid);
			String result = HttpUtil.jsonPost(OPEN_COMPONENT_ACCESS_TOKEN, params);
			JsonObject jsonObject = parser.parse(result).getAsJsonObject();
			String pre_auth_code = jsonObject.get("pre_auth_code").getAsString();
			RedisStringUtil.setDataExpire(preAuthKey, 600, pre_auth_code);
			System.out.println("pre_auth_code:::"+jsonObject);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}




	public String getOpenidByCode(String code, String authorizerAppid, String authorizerAccessToken) {
		String openid = null;
		try {
			Properties P = ConfigUtil.getInstance().getProperties();
			String appid = P.getProperty("APPID");
//			String OPEN_COMPONENT_ACCESS_TOKEN = P.getProperty("OPEN_PRE_AUTH_CODE")+"?component_access_token="+component_access_token;
			String url = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid="+authorizerAppid+"&code="+code+"&grant_type=authorization_code&component_appid="+appid+"&component_access_token="+authorizerAccessToken;
			Map<String, Object> params = new HashMap<String, Object>();
			System.out.println("接口的url是：------------------"+url);

			String result = HttpUtil.jsonPost(url, params);
			System.out.println("接口的结果是：==================="+result);
			JsonObject jsonObject = parser.parse(result).getAsJsonObject();
			if(jsonObject.has("openid")){				
				openid = jsonObject.get("openid").getAsString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return openid;
	}
	
	/**
	 * 
	 * @param str
	 * @param encryptName [MD5 SHA-1 SHA-256]
	 * @return
	 */
	public String encrypt(String str, String encryptName) {
        String returnStr = null;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(encryptName);
            byte[] bytes = messageDigest.digest(str.getBytes("utf-8"));
            StringBuffer stringBuffer = new StringBuffer();
            for (byte b : bytes) {
                int bt = b & 0xFF;
                if (bt < 16) {
                    stringBuffer.append(0);
                }
                stringBuffer.append(Integer.toHexString(bt));
            }
            returnStr = stringBuffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnStr;
    }
	
	public String joinParams(Map<String, String> params, boolean includeNullVal) {
        if (params == null || params.size() == 0) {
            throw new IllegalArgumentException("param is null or empty");
        }
        List<String> keyList = Lists.newArrayList();
        Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
        while(iterator.hasNext()){
        	Entry<String, String> entry = iterator.next();
        	if (checkString(entry.getKey())) {
        		if(includeNullVal){
        			keyList.add(entry.getKey());
        		}else{
        			if(checkString(entry.getValue())){
        				keyList.add(entry.getKey());
        			}
        		}
        	}
        }
        Collections.sort(keyList);
        StringBuilder paramStrBuilder = new StringBuilder();
        for (String key : keyList) {
        	if(includeNullVal){        		
        		paramStrBuilder.append(key);
        		paramStrBuilder.append("=");
        		paramStrBuilder.append(params.get(key).toString());
        		paramStrBuilder.append("&");
        	}else{
        		if(checkString(params.get(key))){
        			paramStrBuilder.append(key);
            		paramStrBuilder.append("=");
            		paramStrBuilder.append(params.get(key).toString());
            		paramStrBuilder.append("&");
        		}
        	}
        }
        int charAt = paramStrBuilder.toString().length() - 1;
        if (charAt > 0) {
            paramStrBuilder.deleteCharAt(charAt);
        }
        return paramStrBuilder.toString();
    }
	
	public boolean checkString(String str) {
        return !(StringUtils.isBlank(str) || Objects.equals("", str.trim()));
    }
}
